class Solution:
    def matrixScore1(self, A):
        """
        :type A: List[List[int]]
        :rtype: int
        """
        n, m = len(A), len(A[0])
        for row in A:
            if row[0] == 0:
                for i in range(len(row)):
                    row[i] = 1 - row[i]
        ans = n
        for j in range(1, m):
            cnt0 = len([A[i][j] for i in range(n) if A[i][j] == 0])
            ans <<= 1
            ans += max(cnt0, n - cnt0)
        return ans
    
    def matrixScoreCore3(self, A, i, nums, byte):
        if i < 0:
            return sum(nums)
        for l in range(len(A)):
            nums[l] ^= byte
        return (self.matrixScoreCore3(A, i - 1, nums, 1), self.matrixScoreCore3(A, i - 1, nums, 0))
    
    def matrixScoreCore(self, A, nums, max_num):
        for i, num in enumerate(nums):
            nums[i] = max(num, max_num - num)
        for i in range(1, len(A[0])):
            sum_byte = 0
            for j in range(len(A)):
                sum_byte += A[j][i]
            if sum_byte < int(len(A) / 2):
                for n, num in enumerate(nums):
                    nums[n] ^= 2 ** i
        
        for i, num in enumerate(nums):
            nums[i] = max(num, max_num - num)
        return sum(nums)
    
    # def matrixScoreCore1(self, A, nums, max_num):
    #     for i, num in enumerate(nums):
    #         sub = max_num - num
    #         if sub in nums:
    #             nums[i] = max_num
    #             k = nums.index(sub)
    #             nums[k] = max_num
    #             for j, num in enumerate(nums):
    #                 if j != k and i!=j:
    #                     nums[j] ^= sub
    #         if num == 0:
    #             nums[i] = max_num
    #             for j, num in enumerate(nums):
    #                 if i != j:
    #                     nums[i] ^= max_num
    #
    #     for i, num in enumerate(nums):
    #         nums[i] = max(num, max_num - num)
    #     return sum(nums)
    
    def matrixScore(self, A):
        """
        :type A: List[List[int]]
        :rtype: int
        """
        if len(A) == 0:
            return 0
        
        if len(A[0]) == 1:
            return len(A)
        
        length = len(A[0])
        max_num = 2 ** length - 1
        nums = []
        for value in A:
            num = 0
            for b in value:
                num = num << 1 | b
            nums.append(num)
        return self.matrixScoreCore(A, nums, max_num)
        # print(self.matrixScoreCore1(A, nums1, max_num),self.matrixScoreCore2(A, nums2, max_num))
        # return max(self.matrixScoreCore1(A, nums1, max_num), self.matrixScoreCore2(A, nums2, max_num))


def main():
    sol = Solution()
    print(sol.matrixScore([[0, 1, 1], [1, 1, 1], [0, 1, 0]]))


if __name__ == "__main__":
    main()
